package com.adtech.adms.system.dao;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import com.adtech.adms.system.SystemConstants;
import com.adtech.adms.system.pojo.Feature;
import com.adtech.adms.system.pojo.Role;
import com.adtech.core.dao.exp.Condition;
import com.adtech.core.dao.exp.Expression;
import com.adtech.core.dao.impl.HibernateDAOImpl;
import com.adtech.core.dao.query.QueryConstants;
import com.adtech.core.dao.query.Sort;

/**
 * 菜单模块数据处理类
 * @author Dormin 
 * @since 2011-6-8 
 * 
 * @Copyright (C) AD Tech Workshop All Right Reserved
 */
public class FeatureDaoImpl extends HibernateDAOImpl implements FeatureDAO {

	@SuppressWarnings("unchecked")
	public List<Feature> getFeaturesByUserId(long id, String filter) {
		StringBuilder builder = new StringBuilder();
		builder.append(" from " + Feature.class.getName() + " this join this.users u");
		builder.append(" where (u." + SystemConstants.User.USER_ID + "=" + id + ") And");
		if (filter != null && !filter.equals("")) {
			builder.append(filter);
		}
		List<Object[]> list = getHibernateTemplate().getSessionFactory().getCurrentSession().createQuery(builder.toString()).list();
		List<Feature> features = new ArrayList<Feature>();
		for (Object[] object : list) {
			features.add((Feature) object[0]);
		}
		return features;
	}

	public List<Feature> getFeaturesByRoles(List<Role> roles) {
		new StringBuilder();
		List<Feature> features = new ArrayList<Feature>();
		Expression expression = null;
		Sort sort = null;
		if (roles != null && roles.size() > 0) {
			List<Expression> expressions = new ArrayList<Expression>();
			for(Role role : roles) {
				expressions.add(Condition.eq(SystemConstants.Feature.ROLES_ROLEID, role.getRoleId()));
			}
			expression = Condition.or(expressions);
			sort = new Sort(SystemConstants.Feature.ORDER_NUMBER,QueryConstants.ASC);
		} else {
			return features;
		}

		List<Feature> list = (List<Feature>) this.getByQueryNoCache(Feature.class, expression, sort);

		for(Feature feature : list) {
			if (!features.contains(feature)) {
				features.add(feature);
			}
		}
		return features;
	}

	public List<Feature> getFeaturesNotRole(Role role) {
		StringBuilder builder = new StringBuilder();

		builder.append("from " + Feature.class.getName() + " this join this.roles u");
		builder.append(" where (");
		builder.append("u." + SystemConstants.Role.ROLE_ID + QueryConstants.HQL_NE + role.getRoleId());
		builder.append(") ");

		List<Object[]> list = getHibernateTemplate().getSessionFactory().getCurrentSession().createQuery(builder.toString()).list();
		List<Feature> features = new ArrayList<Feature>();
		for (Object[] object : list) {
			features.add((Feature) object[0]);
		}
		return features;
	}

	@Override
	public List<Feature> getSubFeatureList(Long rootId) {
		String sql = "feature_id in (select feature_id from sys_feature connect by prior feature_id = parent_id start with feature_id = ?)";
		Expression expression = Condition.decorate(Restrictions.sqlRestriction(sql,rootId,Hibernate.LONG));
		return (List<Feature>) this.getByQuery(Feature.class, expression);
	}

	@Override
	public boolean isHalfChecked(Feature feature, Role role) {
		Criteria criteria = this.getSession().createCriteria(Feature.class);
		criteria.add(Restrictions.sqlRestriction(" {alias}.feature_id in (select t.feature_id from sys_feature t start with feature_id=? CONNECT BY parent_id = PRIOR feature_id) ", feature.getId(), Hibernate.LONG));
		criteria.add(Restrictions.sqlRestriction(" not exists(select fr.feature_id from sys_feature_role fr where fr.role_id = ? and fr.feature_id = {alias}.feature_id) ", role.getRoleId(), Hibernate.LONG));
		criteria.add(Restrictions.sqlRestriction(" {alias}.feature_id !=? ", feature.getId(), Hibernate.LONG));
		List<Long> countList = criteria.setProjection(Projections.rowCount()).list();
		int notCount = 0;
		for (Long c : countList) {
			notCount += c.intValue();
		}
		criteria = this.getSession().createCriteria(Feature.class);
		criteria.add(Restrictions.sqlRestriction(" {alias}.feature_id in (select t.feature_id from sys_feature t start with feature_id=? CONNECT BY parent_id = PRIOR feature_id) ", feature.getId(), Hibernate.LONG));
		criteria.add(Restrictions.sqlRestriction(" exists(select fr.feature_id from sys_feature_role fr where fr.role_id = ? and fr.feature_id = {alias}.feature_id) ", role.getRoleId(), Hibernate.LONG));
		criteria.add(Restrictions.sqlRestriction(" {alias}.feature_id !=? ", feature.getId(), Hibernate.LONG));
		countList = criteria.setProjection(Projections.rowCount()).list();
		int count = 0;
		for (Long c : countList) {
			count += c.intValue();
		}
		if(count > 0 && notCount > 0) {
			return true;
		}
 		return false;
	}

}
